package com.weasel.weixin.commons.session;

import com.weasel.helper.TimeHelper;
import com.weasel.weixin.commons.exception.ExpiredSessionException;
import com.weasel.weixin.commons.exception.InvalidSessionException;
import com.weasel.weixin.commons.exception.SessionStopedException;
import com.weasel.weixin.commons.session.mgt.AbstractWeixinSessionManager;

import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by Dylan on 2015/12/7.
 */
public class SimpleWeixinSession implements WeixinValidatingSession {

    private String id;
    private Date startTime;
    private Date lastAccessTime;
    private Date stopTime;
    private long timeout;
    private Map<Object,Object> attributes = new HashMap<>();

    public SimpleWeixinSession() {
        this.timeout = AbstractWeixinSessionManager.DEFAULT_GLOBAL_SESSION_TIMEOUT;
        this.startTime = new Date();
        this.lastAccessTime = new Date();
    }

    @Override
    public boolean isValid() {
        return !isExpired() && !isStoped();
    }

    @Override
    public void validate() throws InvalidSessionException {

        if(isStoped()){
            String msg = "session with id ["+this.id+"] had stoped";
            throw new SessionStopedException(msg);
        }

        if(isExpired()){
            stop();
            String msg = "session with id ["+this.id+"] had expired, access time is ["+ TimeHelper.dateToString(this.lastAccessTime)+"],but now is ["+TimeHelper.getCurrentTime()+"]";

            throw new ExpiredSessionException(msg);
        }
    }

    @Override
    public String getId() {
        return this.id;
    }

    public void setId(String id) {
        this.id = id;
    }

    @Override
    public Date getStartTime() {
        return startTime;
    }

    @Override
    public Date getLastAccessTime() {
        return lastAccessTime;
    }

    @Override
    public long getTimeout() {
        return timeout;
    }

    @Override
    public void setTimeout(long maxIdleTimeInMillis) {
        timeout = maxIdleTimeInMillis;
    }

    /**
     * 停止session
     */
    @Override
    public void stop() {
        if(null == this.stopTime){
            this.stopTime = new Date();
        }
    }

    /**
     * 是否已经停止
     * @return
     */
    public boolean isStoped(){
        return this.stopTime != null;
    }

    /**
     * 是否已经过期
     * @return
     */
    public boolean isExpired(){
        return this.lastAccessTime.before(new Date(System.currentTimeMillis() - this.timeout));
    }

    @Override
    public Collection<Object> getAttributeKeys() {
        return attributes.keySet();
    }

    @Override
    public Object getAttribute(Object key) {
        return attributes.get(key);
    }

    @Override
    public void setAttribute(Object key, Object value) {

        attributes.put(key,value);
    }

    @Override
    public Object removeAttribute(Object key) {

        return attributes.remove(key);
    }
}
